
package org.apache.solr.update.processor;

import java.io.IOException;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.update.*;

/**
 * Executes the update commands using the underlying UpdateHandler.
 * Allmost all processor chains should end with an instance of 
 * <code>RunUpdateProcessorFactory</code> unless the user is explicitly 
 * executing the update commands in an alternative custom 
 * <code>UpdateRequestProcessorFactory</code>
 * 
 * @since solr 1.3
 * @see DistributingUpdateProcessorFactory
 */
public class RunUpdateProcessorFactory extends UpdateRequestProcessorFactory {

    @Override
    public UpdateRequestProcessor getInstance(SolrQueryRequest req, SolrQueryResponse rsp, UpdateRequestProcessor next) {
        return new RunUpdateProcessor(req, next);
    }
}

class RunUpdateProcessor extends UpdateRequestProcessor {

    private final SolrQueryRequest req;
    private final UpdateHandler updateHandler;
    private boolean changesSinceCommit = false;

    public RunUpdateProcessor(SolrQueryRequest req, UpdateRequestProcessor next) {
        super(next);
        this.req = req;
        this.updateHandler = req.getCore().getUpdateHandler();
    }

    @Override
    public void processAdd(AddUpdateCommand cmd) throws IOException {
        updateHandler.addDoc(cmd);
        super.processAdd(cmd);
        changesSinceCommit = true;
    }

    @Override
    public void processDelete(DeleteUpdateCommand cmd) throws IOException {
        if (cmd.isDeleteById()) {
            updateHandler.delete(cmd);
        }
        else {
            updateHandler.deleteByQuery(cmd);
        }
        super.processDelete(cmd);
        changesSinceCommit = true;
    }

    @Override
    public void processMergeIndexes(MergeIndexesCommand cmd) throws IOException {
        updateHandler.mergeIndexes(cmd);
        super.processMergeIndexes(cmd);
    }

    @Override
    public void processCommit(CommitUpdateCommand cmd) throws IOException {
        updateHandler.commit(cmd);
        super.processCommit(cmd);
        changesSinceCommit = false;
    }

    /**
     * @since Solr 1.4
     */
    @Override
    public void processRollback(RollbackUpdateCommand cmd) throws IOException {
        updateHandler.rollback(cmd);
        super.processRollback(cmd);
        changesSinceCommit = false;
    }

    @Override
    public void finish() throws IOException {
        if (changesSinceCommit && updateHandler.getUpdateLog() != null) {
            updateHandler.getUpdateLog().finish(null);
        }
        super.finish();
    }
}
